常用的排序算法分析:选择排序,冒泡排序,插入排序
选择排序
算法原理
首先遍历数组找到最小(大)元素,存放到数组的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void selectSort(int a[]) { int len = a.size(); int min_index; if(len <= 1)return; for(int i=0;i<len;++i){ min_index=i; for(int j=i;j<len;++j){ if(a[min_index]>a[j]){ min_index=j; } } int temp=a[i]; a[i]=a[min_index]; a[min_index]=temp; } }
|
性质
最稳定的排序算法
最坏,最好和平均时间复杂度总是$O(N^2)$
冒泡排序
算法原理
顺序依次相邻元素比较,大的往后移(从小到大排序),这样能保证一轮过后最大的数在最后面。再进行一轮比较得到第二大的数,依次类推。

N个数排序需要重复N-1次;
第K次排序时,证明已经有K个数排好序,不需要再排。则第K次需要的比较的次数为(N-1-K)次;
所以可以用双重循环语句,外层控制循环多少趟,内层控制每一趟的循环次数
1 2 3 4 5 6 7 8 9
| void BubbleSort(int a[]){ int len=a.size(); if(len<=1)return; for(int i=0;i<len-1;i++){ for(int j=0;j<len-1-i;++j){ if(a[j]>a[j+1])swap(a[j],a[j+1]); } } }
|
改进:当数组已经排好序时,可以直接跳出循环得到结果。不需要再做比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void BubbleSort(int a[]){ int len=a.size(); bool flag=true; if(len<=1)return; for(int i=0;i<len-1 && flag;i++){ flag=false; for(int j=0;j<len-1-i;++j){ if(a[j]>a[j+1]){ swap(a[j],a[j+1]); flag=true; } } } }
|
性质
时间复杂度
- 最好:$O(N)$。在数组已经是正序的情况下,只需要遍历一遍就可以跳出循环。
- 最坏:$O(N^2)$。在数组逆序的情况下。
- 平均:$O(N^2)$。
稳定排序
插入排序
算法原理
对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入

1 2 3 4 5 6 7 8 9 10 11 12 13
| void insertSort(int a[]) { int len = a.size(); if(len<=1)return; for(int i=1;i<len-1;++i){ int j=i-1; int key=a[i]; while( j>=0 && key>a[j] ){ a[j+1]=a[j]; --j; } a[j+1]=key; } }
|
性质
时间复杂度:
- 最好:$O(N)$。已经排好序的数组。遍历一遍。
- 最坏:$O(N^2)$。逆序
- 平均:$O(N^2)$。
不稳定排序:
序列5 8 5 2 9,第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
参考